using System;
using System.Data;
using System.Windows.Forms;
using TUnit.Data;
using TUnit.Class;
namespace viclip
{
    ///<summary>
    ///Date init:  
    ///Date modify:
    ///By:
    ///
    ///</summary>
    public class CAccount : Class
    {
        #region Declares
        string _email = "";
        string _password = "";
        string _telephone = "";
        string _fullname = "";
        string _CMND = "";
        string _address = "";
        #endregion

        #region Constructors
        public CAccount()
        {
        }
        public CAccount(CLogin Login)
        {
            base.Login = Login;
        }
        public CAccount(CLogin Login, object ObjId)
        {
            base.Login = Login;
            using (AccDBAccount db = new AccDBAccount())
            {
                this.Populate((CAccount)db.GetClass(Login, ObjId));
            }
        }
        public CAccount(CLogin Login, IProvider p, System.Data.DataRow dr)
        {
            base.Login = Login;
            this.Populate(p, dr);
        }
        public CAccount(CLogin Login, IProvider p, object ObjId)
        {
            base.Login = Login;
            using (AccDBAccount db = new AccDBAccount())
            {
                this.Populate((CAccount)db.GetClass(Login, p, ObjId));
            }
        }
        #endregion

        #region Methods
        public void Populate(IProvider p, DataRow dr)
        {
            if (dr != null)
            {
                try
                {
                    if (dr.Table.Columns.IndexOf("email") >= 0)
                    {
                        this._email = (dr["email"] != DBNull.Value ? Convert.ToString(dr["email"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD email [nvarchar] (50) NULL");
                    //}
                    if (dr.Table.Columns.IndexOf("password") >= 0)
                    {
                        this._password = (dr["password"] != DBNull.Value ? Convert.ToString(dr["password"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD password [nvarchar] (50) NULL");
                    //}
                    if (dr.Table.Columns.IndexOf("telephone") >= 0)
                    {
                        this._telephone = (dr["telephone"] != DBNull.Value ? Convert.ToString(dr["telephone"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD telephone [nvarchar] (50) NULL");
                    //}
                    if (dr.Table.Columns.IndexOf("fullname") >= 0)
                    {
                        this._fullname = (dr["fullname"] != DBNull.Value ? Convert.ToString(dr["fullname"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD fullname [nvarchar] (50) NULL");
                    //}
                    if (dr.Table.Columns.IndexOf("CMND") >= 0)
                    {
                        this._CMND = (dr["CMND"] != DBNull.Value ? Convert.ToString(dr["CMND"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD CMND [nvarchar] (50) NULL");
                    //}
                    if (dr.Table.Columns.IndexOf("address") >= 0)
                    {
                        this._address = (dr["address"] != DBNull.Value ? Convert.ToString(dr["address"]) : "");
                    }
                    //else
                    //{//Tao Field neu bang CSDL chua ton tai Field nay
                    //	p.ExecuteNonQuery("ALTER TABLE tblAccounts ADD address [nvarchar] (50) NULL");
                    //}
                }
                catch { }
            }
        }
        public void Populate(CAccount Obj)
        {
            if (Obj != null)
            {
                try
                {
                    this._email = Obj.email;
                    this._password = Obj.password;
                    this._telephone = Obj.telephone;
                    this._fullname = Obj.fullname;
                    this._CMND = Obj.CMND;
                    this._address = Obj.address;
                }
                catch { }
            }
        }
        public override bool Save()
        {
            using (IProvider p = new OleDb(Login.Connectionstring))
            {
                if (p.Open())
                {
                    p.OpenTransaction();
                    using (AccDBAccount db = new AccDBAccount())
                    {
                        if (this.EventSaving != null)
                            this.EventSaving(this);
                        if (db.Save(p, this))
                        {
                            p.CloseTransaction();
                            p.Close();
                            if (this.EventSaved != null)
                                this.EventSaved(this);
                            return true;
                        }
                        else
                        {
                            p.Rollback();
                            p.CloseTransaction();
                            p.Close();
                            if (this.EventSaveError != null)
                                this.EventSaveError(this);
                            return false;
                        }
                    }
                }
            }
            return false;
        }
        public override bool Save(IProvider p)
        {
            using (AccDBAccount db = new AccDBAccount())
            {
                if (db.Save(p, this))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public override bool Delete()
        {
            using (IProvider p = new OleDb(Login.Connectionstring))
            {
                if (p.Open())
                {
                    p.OpenTransaction();
                    using (AccDBAccount db = new AccDBAccount())
                    {
                        if (this.EventDeleting != null)
                            this.EventDeleting(this);
                        if (db.Delete(p, this))
                        {
                            p.CloseTransaction();
                            p.Close();
                            if (this.EventDeleted != null)
                                this.EventDeleted(this);
                            return true;
                        }
                        else
                        {
                            p.Rollback();
                            p.CloseTransaction();
                            p.Close();
                            if (this.EventDeleteError != null)
                                this.EventDeleteError(this);
                            return false;
                        }
                    }
                }
            }
            return false;
        }
        public override bool Delete(IProvider p)
        {
            using (AccDBAccount db = new AccDBAccount())
            {
                if (db.Delete(p, this))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        #endregion

        #region Events
        public delegate void OnEventSaveError(CAccount obj);
        public event OnEventSaveError EventSaveError;
        public delegate void OnEventSaving(CAccount Account);
        public event OnEventSaving EventSaving;
        public delegate void OnEventSaved(CAccount Account);
        public event OnEventSaved EventSaved;
        public delegate void OnEventDeleting(CAccount Account);
        public event OnEventSaving EventDeleting;
        public delegate void OnEventDeleted(CAccount Account);
        public event OnEventDeleted EventDeleted;
        public delegate void OnEventDeleteError(CAccount obj);
        public event OnEventDeleteError EventDeleteError;
        #endregion

        #region Properties
        public string email
        {
            get { return this._email; }
            set
            {
                if (this._email != value)
                {
                    this._email = value;
                }
            }
        }
        public string password
        {
            get { return this._password; }
            set
            {
                if (this._password != value)
                {
                    this._password = value;
                }
            }
        }
        public string telephone
        {
            get { return this._telephone; }
            set
            {
                if (this._telephone != value)
                {
                    this._telephone = value;
                }
            }
        }
        public string fullname
        {
            get {
                if (_fullname == "")
                {
                    int i = email.IndexOf("@");
                    if (i > 0)
                        _fullname = email.Substring(0, i);

                }
                return this._fullname; 
            }
            set
            {
                if (this._fullname != value)
                {
                    this._fullname = value;
                }
            }
        }
        public string CMND
        {
            get { return this._CMND; }
            set
            {
                if (this._CMND != value)
                {
                    this._CMND = value;
                }
            }
        }
        public string address
        {
            get { return this._address; }
            set
            {
                if (this._address != value)
                {
                    this._address = value;
                }
            }
        }

        CCollection _AccLevels = null;
        public CCollection AccLevels
        {
            get
            {
                if (_AccLevels == null)
                {
                    using (AccDBAccLevel db = new AccDBAccLevel())
                    {
                        CCollection tmp = new CCollection();
                        db.GetCollection(this, tmp);
                        this._AccLevels = tmp;
                    }
                }
                return this._AccLevels;
            }
        }
        int _accountOrder = -1;

        public int AccountOrder
        {
            get {
                if (_accountOrder == -1)
                {
                    if (TopAccounts != null)
                    {
                        for (int i = 0; i < TopAccounts.Count; i++)
                        {
                            CAccount a = (CAccount)TopAccounts[i];
                            if (a.email == this.email)
                                _accountOrder = i + 1;
                        }
                    }
                }
                return _accountOrder; }
            set { _accountOrder = value; }
        }

        int _answerSecond = 0;
        public int AnswerSecond
        {
            get
            {
                return _answerSecond;
            }
            set { _answerSecond = value; }
        }
        CCollection _topAccounts = null;
        public CCollection TopAccounts 
        {
            get
            {
                if (_topAccounts == null)
                {
                    using (AccDBAccount db = new AccDBAccount())
                    {
                        CCollection tmp = new CCollection();
                        db.GetCollection(this, tmp);
                        this._topAccounts = tmp;
                    }
                }
                return this._topAccounts;
            }
        }

        CGameLevels _gameLevelCurrent = null;

        public CGameLevels GameLevelCurrent
        {
            get {
                if (_gameLevelCurrent == null)
                {
                    if (AccLevels != null && AccLevels.Count > 0)
                    {
                        _gameLevelCurrent = ((CAccLevel)AccLevels[AccLevels.Count - 1]).gameLevel;
                    }
                }
                return _gameLevelCurrent; }
            set { _gameLevelCurrent = value; }
        }
        CAccLevel _accLevelCurrent = null;
        public CAccLevel AccLevelCurrent
        {
            get
            {
                if (_accLevelCurrent == null)
                {
                    if (AccLevels != null && AccLevels.Count > 0)
                    {
                        _accLevelCurrent = (CAccLevel)AccLevels[AccLevels.Count - 1];
                    }
                }
                return _accLevelCurrent;
            }
            set { _accLevelCurrent = value; }
        }
        #endregion
    }

    #region Class AccDB
    public class AccDBAccount : AccDB
    {
        /// <summary>
        /// 
        /// </summary>
        public AccDBAccount()
        {
        }
        /// <summary>
        ///Phuong thuc dung dien du lieu len Combo 
        /// </summary>
        /// <param name="Login"></param>
        /// <param name="cmb"></param>
        /// <param name="extName"></param>
        public override void FillComboBox(CLogin Login, ComboBox cmb, string extName)
        {
            IProvider p = new OleDb(Login.Connectionstring);
            if (p.Open())
            {
                string sql = "SELECT AccountId, AccountName";
                sql += " FROM  tblAccounts";
                sql += " WHERE (AccountId >= 0)";
                sql += " ORDER BY AccountName";
                DataTable table = p.OpenTable(sql, "tblAccounts");
                if (table != null)
                {
                    if (extName != "")
                    {
                        System.Data.DataRow row = table.NewRow();
                        row["AccountName"] = extName;
                        row["AccountId"] = "-1";
                        table.Rows.Add(row);
                    }
                    cmb.DataSource = table;
                    cmb.DisplayMember = "AccountName";
                    cmb.ValueMember = "AccountId";
                    p.Close();
                }
            }
        }
        /// <summary>
        ///Doc doi tuong tu CSDL theo ID chi dinh
        /// </summary>
        /// <param name="p"></param>
        /// <param name="ObjId"></param>
        /// <returns></returns>
        public override Class GetClass(CLogin Login, IProvider p, object ObjId)
        {
            try
            {
                string sql = "SELECT * FROM tblAccounts WHERE (email='" + ObjId + "')";
                DataTable table = p.OpenTable(sql, "tblAccounts");
                if ((table != null) && (table.Rows.Count > 0))
                {
                    return new CAccount(Login, p, table.Rows[0]);
                }
            }
            catch
            {
            }
            return null;
        }
        /// <summary>
        /// Luu doi tuong vao CSDL
        /// </summary>
        /// <param name="p"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Save(IProvider p, Class obj)
        {
            CAccount Account = (CAccount)obj;
            string sql = "SELECT * FROM tblAccounts";
            sql += " WHERE email='" + Account.email + "'";
            DataTable dt = p.OpenTable(sql, "tblAccounts");
            if (dt != null)
            {
                DataRow row = null;
                if (dt.Rows.Count == 1)
                {
                    row = dt.Rows[0];
                }
                else
                {
                    row = dt.NewRow();
                    dt.Rows.Add(row);
                }
                row["email"] = Account.email;
                row["password"] = Account.password;
                row["telephone"] = Account.telephone;
                row["fullname"] = Account.fullname;
                row["CMND"] = Account.CMND;
                row["address"] = Account.address;
                if (!p.UpdateTable("tblAccounts", dt))
                {
                    return false;
                }
                return true;
            }
            return false;
        }
        /// <summary>
        ///Xoa doi tuong khoi CSDL 
        /// </summary>
        /// <param name="p"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Delete(IProvider p, Class obj)
        {
            CAccount Account = (CAccount)obj;
            string sql = "DELETE FROM tblAccounts";
            sql += " WHERE email='" + Account.email + "'";
            return p.ExecuteNonQuery(sql);
        }
        /// <summary>
        /// Lay ve danh sach cac doi tuong tren CSDL
        /// </summary>
        /// <param name="p"></param>
        /// <param name="Collection"></param>
        public override void GetCollection(CLogin Login, IProvider p, CCollection Collection)
        {
            string sql = "SELECT * FROM tblAccounts ORDER BY AccountName";
            DataTable table = p.OpenTable(sql, "tblAccounts");
            if (table != null)
            {
                foreach (DataRow row in table.Rows)
                {
                    CAccount o = new CAccount(Login, p, row);
                    Collection.Add(o);
                }
            }
        }
        /// <summary>
        /// Lay ve danh sach cac doi tuong con cua doi obj neu co (danh cho loai du lieu quan he 2 bang cha con)
        /// </summary>
        /// <param name="Login"></param>
        /// <param name="Collection"></param>
        public override void GetCollection(IProvider p, Class obj, CCollection Collection)
        {
            if (obj is CAccount)
            {
                string sql = "SELECT tblAccounts.* FROM tblAccounts INNER JOIN";
                sql += " tblAccLevel ON tblAccounts.email = tblAccLevel.email";
                sql += " WHERE(tblAccLevel.retest > 0) AND (tblAccLevel.gameLevelId = " + ((CAccount)obj).GameLevelCurrent.gameLevelId + ")";
                sql += " ORDER BY dbo.tblAccLevel.score DESC";
                DataTable table = p.OpenTable(sql, "tblAccLevel");
                if (table != null)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        CAccount o = new CAccount(obj.Login, p, row);
                        Collection.Add(o);
                    }
                }
            }
            if (obj is CQuestion)
            {
                string sql = "SELECT TOP 3 tblAccounts.*, tblAccountAndQuestions.answerSecond";
                sql += " FROM tblAccounts INNER JOIN";
                sql += " tblAccountAndQuestions ON tblAccounts.email = tblAccountAndQuestions.email";
                sql += " WHERE (tblAccountAndQuestions.questionsId = " + ((CQuestion)obj).questionsId + ") ORDER BY tblAccountAndQuestions.answerDate DESC";
                DataTable table = p.OpenTable(sql, "tblAccounts");
                if (table != null)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        CAccount o = new CAccount(obj.Login, p, row);
                        o.AnswerSecond = (int)row["answerSecond"];
                        Collection.Add(o);
                    }
                }
            }
        }
    }
    #endregion
}
